/*
 * Copyright (C) 2012, EADS France
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */
package xowl.gmi.view;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListDataListener;

/**
 *
 * @author Laurent WOUTERS
 */
public class CheckBoxList extends JList {
    private static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

    private List<JCheckBox> content;
    private List<ListDataListener> listeners;
    
    public void addCheckbox(String name) {
        content.add(new javax.swing.JCheckBox(name));
        javax.swing.event.ListDataEvent e = new javax.swing.event.ListDataEvent(this, javax.swing.event.ListDataEvent.CONTENTS_CHANGED, content.size()-1, content.size()-1);
        for (ListDataListener l : listeners)
            l.contentsChanged(e);
        repaint();
    }
    
    public List<String> getSelected() {
        List<String> result = new ArrayList<>();
        for (JCheckBox box : content)
            if (box.isSelected())
                result.add(box.getText());
        return result;
    }
    
    public void selectAll() {
        for (JCheckBox box : content)
            box.setSelected(true);
        repaint();
    }
    
    public void selectNone() {
        for (JCheckBox box : content)
            box.setSelected(false);
        repaint();
    }
    
    public CheckBoxList() {
        content = new ArrayList<>();
        listeners = new ArrayList<>();
        this.setModel(new javax.swing.ListModel<JCheckBox>() {
            @Override public int getSize() { return content.size(); }
            @Override public JCheckBox getElementAt(int index) { return content.get(index); }
            @Override public void addListDataListener(ListDataListener l) { listeners.add(l); }
            @Override public void removeListDataListener(ListDataListener l) { listeners.remove(l); }
        });
        setCellRenderer(new CellRenderer());
        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                int index = locationToIndex(e.getPoint());
                if (index != -1) {
                    JCheckBox checkbox = content.get(index);
                    checkbox.setSelected(!checkbox.isSelected());
                    repaint();
                }
            }
        });
        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        this.setBorder(javax.swing.BorderFactory.createLineBorder(Color.BLACK));
    }

    protected class CellRenderer implements ListCellRenderer {

        public Component getListCellRendererComponent(
                JList list, Object value, int index,
                boolean isSelected, boolean cellHasFocus) {
            JCheckBox checkbox = content.get(index);
            checkbox.setBackground(isSelected
                    ? getSelectionBackground() : getBackground());
            checkbox.setForeground(isSelected
                    ? getSelectionForeground() : getForeground());
            checkbox.setEnabled(isEnabled());
            checkbox.setFont(getFont());
            checkbox.setFocusPainted(false);
            checkbox.setBorderPainted(true);
            checkbox.setBorder(isSelected
                    ? UIManager.getBorder(
                    "List.focusCellHighlightBorder") : noFocusBorder);
            return checkbox;
        }
    }
}
